#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <strings.h>
#include <sys/ioctl.h>
#include <sys/stat.h>

#include "include/Log.h"
#include "virtual_serial.h"
#include <sys/system_properties.h>

#define EVILINK_VITUAL_SERIAL  "/dev/lynxCarPlay_serial"

#define PROPERTY_VALUE_MAX 92
static char board_platform[PROPERTY_VALUE_MAX] = { 0 };

void (*pOnATCommandRequest)(const char * command,int size);

int fd_master = -1;
int fd_gnss = -1;

int open_ptms(const char* target) {
	int fdm = open("/dev/ptmx", O_RDWR); /* open master */
	if (fdm < 0) {
		LOGD("open /dev/ptmx error \n");
		return -1;
	}
	LOGD("open /dev/ptmx succeed");
	grantpt(fdm); /* change permission of slave */
	unlockpt(fdm); /* unlock slave */
	char *slavename = ptsname(fdm); /* get name of slave */
	LOGD("slave name is %s", slavename);
	unlink(target);
	if (0 != chmod(slavename, 0777)) {
		LOGD("chmod 0666 slave error\n");
	}
	if (0 != symlink(slavename, target)) {
		LOGD("link %s to %s error", slavename, target);
		return -3;
	}
	LOGD("SharkCarPlay --> link %s to %s succeed %d\n", slavename, target, fdm);
	return fdm;
}
static char serialBuf [1024];
void *	_GeneralSerialThread( void *inArg )
{
	for(;;)
	{
		usleep(1000*20);//20 ms each loop
		memset(serialBuf,0,1024);
		int ret = -1;
		ret = read(fd_master,serialBuf,1024);
		if(ret > 0)
		{
			//读取到了数据
			LOGD("_GeneralSerialThread read buf = %s", serialBuf);
			if(strlen(serialBuf) > 0)
			{
				if(pOnATCommandRequest!=NULL)
				{
					pOnATCommandRequest( serialBuf, ret );
				}
			}
		}
	}
	return( NULL );
}

void init_serial(void (*pFunc)(const char* command,int size)) {
	pOnATCommandRequest = pFunc;
	__system_property_get("ro.board.platform", board_platform);

	if (strcmp(board_platform, "msm8953") == 0) {
		//sd450
//		fd_master = open_ptms("/dev/carplaySvc_serial");
		fd_master = open_ptms(EVILINK_VITUAL_SERIAL);
	}else{
		fd_master = open_ptms(EVILINK_VITUAL_SERIAL);
	}
	if(fd_master > 0)
	{
		pthread_t		    ptmxTid;
		int				    err;
		err = pthread_create( &ptmxTid, NULL, _GeneralSerialThread, NULL );
	}
	init_gnss_serial();
}

int write_serial(char* atCommand){
	if(fd_master > 0 && atCommand !=NULL )
	{
		int ret = write(fd_master, atCommand, strlen(atCommand));
		LOGD("SharkCarPlay write_serial:  %s  %d\n", atCommand, ret);
		return ret;
	}
	return -1;
}


void init_gnss_serial() {
	fd_gnss = open_ptms("/dev/zj_gps");
	if(fd_gnss > 0)
	{
		LOGD("SharkCarPlay GNSS_serial init success.\n");
	}
}

int write_gnss_serial(char* data){
	if(fd_gnss > 0 && data !=NULL )
	{
		int ret = write(fd_gnss, data, strlen(data));
		LOGD("SharkCarPlay write GNSS serial:  %s  %d\n", data, ret);
		return ret;
	}
	return -1;
}
